package com.powernode.driver.service.impl;


import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.powernode.common.constant.SystemConstant;
import com.powernode.driver.mapper.*;
import com.powernode.driver.properties.TencentProperties;
import com.powernode.driver.service.CosService;
import com.powernode.driver.service.DriverInfoService;
import com.powernode.model.entity.driver.*;
import com.powernode.model.form.driver.DriverFaceModelForm;
import com.powernode.model.form.driver.UpdateDriverAuthInfoForm;
import com.powernode.model.vo.driver.DriverAuthInfoVo;
import com.powernode.model.vo.driver.DriverInfoVo;
import com.powernode.model.vo.driver.DriverLoginVo;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.iai.v20180301.IaiClient;
import com.tencentcloudapi.iai.v20180301.models.CreatePersonRequest;
import com.tencentcloudapi.iai.v20180301.models.CreatePersonResponse;
import com.tencentcloudapi.iai.v20180301.models.VerifyFaceRequest;
import com.tencentcloudapi.iai.v20180301.models.VerifyFaceResponse;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.Date;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class DriverInfoServiceImpl extends ServiceImpl<DriverInfoMapper, DriverInfo> implements DriverInfoService {

    @Resource
    private WxMaService wxMaService;

    @Resource
    private DriverSetMapper driverSetMapper;

    @Resource
    private DriverAccountMapper driverAccountMapper;

    @Resource
    private DriverLoginLogMapper driverLoginLogMapper;


    @Resource
    private CosService cosService;

    @Resource
    private TencentProperties tencentProperties;

    @Resource
    private DriverFaceRecognitionMapper driverFaceRecognitionMapper;

    /**
     * 配送员登录
     * 1.获取openid
     * 2.根据openId查询配送员数据
     * 3.存在 则返回配送员信息
     * 4.不存在 则插入配送员信息 再返回
     * 5.初始化默认接单数据
     * 6.初始化账户数据
     */
    @Transactional
    @Override
    public Long login(String code) {
        try {
            //1.获取openid
            WxMaJscode2SessionResult sessionInfo = wxMaService.getUserService().getSessionInfo(code);
            String openid = sessionInfo.getOpenid();

            //2.根据openId查询配送员数据
            LambdaQueryWrapper<DriverInfo> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(DriverInfo::getWxOpenId, openid);

            DriverInfo driverInfo = getOne(queryWrapper);

            //4.不存在 则插入配送员信息 再返回
            if (driverInfo == null) {
                driverInfo = new DriverInfo();
                driverInfo.setWxOpenId(openid);
                driverInfo.setStatus(1);
                driverInfo.setNickname(String.valueOf(System.currentTimeMillis()));
                driverInfo.setAvatarUrl("images/avatar.png");
                save(driverInfo);


                //5.初始化默认接单数据
                DriverSet driverSet = new DriverSet();
                driverSet.setDriverId(driverInfo.getId());
                driverSet.setAcceptDistance(new BigDecimal(SystemConstant.ACCEPT_DISTANCE));
                driverSet.setOrderDistance(BigDecimal.ZERO);
                driverSet.setIsAutoAccept(0);//手动接单
                driverSet.setServiceStatus(0);//是否开启接单
                driverSetMapper.insert(driverSet);

                //6.初始化账户数据
                DriverAccount driverAccount = new DriverAccount();
                driverAccount.setDriverId(driverInfo.getId());

                driverAccountMapper.insert(driverAccount);

                //7.记录日志
                DriverLoginLog driverLoginLog = new DriverLoginLog();
                driverLoginLog.setDriverId(driverInfo.getId());
                driverLoginLog.setStatus(true);
                driverLoginLog.setMsg("登录成功");

                driverLoginLogMapper.insert(driverLoginLog);

                return driverInfo.getId();

            }
        } catch (WxErrorException e) {
            throw new RuntimeException(e);
        }
        return null;
    }


    /**
     * 获取配送员的登录信息
     */
    @Override
    public DriverLoginVo getDriverLoginInfo(Long driverId) {
        DriverInfo driverInfo = getById(driverId);

        DriverLoginVo driverLoginVo = new DriverLoginVo();

        BeanUtils.copyProperties(driverInfo, driverLoginVo);

        //是否进行人脸识别
        boolean isFace = StringUtils.hasText(driverInfo.getFaceModelId());
        driverLoginVo.setIsArchiveFace(isFace);

        return driverLoginVo;
    }

    /**
     * 获取配送员认证信息
     */
    @Override
    public DriverAuthInfoVo getDriverAuthInfo(Long driverId) {
        DriverInfo driverInfo = getById(driverId);

        DriverAuthInfoVo driverAuthInfoVo = new DriverAuthInfoVo();
        BeanUtils.copyProperties(driverInfo, driverAuthInfoVo);

        driverAuthInfoVo.setDriverId(driverId);

        driverAuthInfoVo.setIdcardFrontShowUrl(cosService.getImageUrl(driverAuthInfoVo.getIdcardFrontUrl()));
        driverAuthInfoVo.setIdcardBackShowUrl(cosService.getImageUrl(driverAuthInfoVo.getIdcardBackUrl()));
        driverAuthInfoVo.setIdcardHandShowUrl(cosService.getImageUrl(driverAuthInfoVo.getIdcardHandUrl()));

        return driverAuthInfoVo;
    }


    /**
     * 修改配送员认证信息
     */
    @Override
    public Boolean updateDriverAuthInfo(UpdateDriverAuthInfoForm driverAuthInfoForm) {
        DriverInfo driverInfo = new DriverInfo();
        BeanUtils.copyProperties(driverAuthInfoForm, driverInfo);
        driverInfo.setId(driverAuthInfoForm.getDriverId());

        return updateById(driverInfo);
    }

    /**
     * 创建人脸信息
     */
    @Override
    public Boolean createDriverFaceModel(DriverFaceModelForm driverFaceModelForm) {
        DriverInfo driverInfo = getById(driverFaceModelForm.getDriverId());

        Credential cred = new Credential(tencentProperties.getSecretId(), tencentProperties.getSecretKey());

        //构建请求对象
        CreatePersonRequest request = new CreatePersonRequest();
        //设置用户的人脸库信息
        request.setGroupId(tencentProperties.getPersionGroupId());
        request.setPersonId(driverInfo.getId().toString());
        request.setGender(Long.parseLong(driverInfo.getGender()));
        request.setQualityControl(4L);
        request.setUniquePersonControl(4L);
        request.setPersonName(driverInfo.getName());
        request.setImage(driverFaceModelForm.getImageBase64());

        //发送请求获取响应
        IaiClient iaiClient = new IaiClient(cred, tencentProperties.getRegion());
        try {
            CreatePersonResponse response = iaiClient.CreatePerson(request);
            String faceId = response.getFaceId();
            if (StringUtils.hasText(faceId)) {
                driverInfo.setFaceModelId(faceId);

                updateById(driverInfo);
            }

            return true;
        } catch (TencentCloudSDKException e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 获取配送员的个性化接单设置
     */
    @Override
    public DriverSet getDriverSet(Long driverId) {
        LambdaQueryWrapper<DriverSet> queryWrapper = new LambdaQueryWrapper<DriverSet>()
                .eq(DriverSet::getDriverId, driverId);

        DriverSet driverSet = driverSetMapper.selectOne(queryWrapper);

        return driverSet;
    }


    /**
     * 查看配送员当天是否进行人脸识别
     */
    @Override
    public Boolean isFaceRecognition(Long driver) {
        LambdaQueryWrapper<DriverFaceRecognition> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.eq(DriverFaceRecognition::getDriverId, driver);
        //当天日期
        queryWrapper.eq(DriverFaceRecognition::getFaceDate, new DateTime().toString("yyyy-MM-dd"));

        Long count = driverFaceRecognitionMapper.selectCount(queryWrapper);
        return count != 0;

    }


    /**
     * 人脸识别
     */
    @Override
    public Boolean verifyDriverFace(DriverFaceModelForm driverFaceModelForm) {
        try {
            Credential credential = new Credential(tencentProperties.getSecretId(), tencentProperties.getSecretKey());

            HttpProfile httpProfile = new HttpProfile();
            httpProfile.setEndpoint("iai.tencentcloudapi.com");
            ClientProfile clientProfile = new ClientProfile();
            clientProfile.setHttpProfile(httpProfile);

            IaiClient iaiClient = new IaiClient(credential, tencentProperties.getRegion(), clientProfile);

            //构建人脸识别请求
            VerifyFaceRequest faceRequest = new VerifyFaceRequest();

            faceRequest.setImage(driverFaceModelForm.getImageBase64());
            faceRequest.setPersonId(driverFaceModelForm.getDriverId().toString());
            //发送请求获取响应
            VerifyFaceResponse faceResponse = iaiClient.VerifyFace(faceRequest);

            if (faceResponse.getIsMatch()) {
                //活体检测
                //人脸识别通过 向数据库中添加数据
                DriverFaceRecognition driverFaceRecognition = new DriverFaceRecognition();
                driverFaceRecognition.setDriverId(driverFaceModelForm.getDriverId());
                driverFaceRecognition.setFaceDate(new Date());

                driverFaceRecognitionMapper.insert(driverFaceRecognition);
                return true;
            }


        } catch (TencentCloudSDKException e) {
            throw new RuntimeException(e);
        }

        return false;
    }


    /**
     * 修改配送员接单状态
     */
    @Override
    public Boolean updateServiceStatus(Long driverId, Integer status) {
        LambdaQueryWrapper<DriverSet> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DriverSet::getDriverId, driverId);
        DriverSet driverSet = new DriverSet();
        driverSet.setServiceStatus(status);

        driverSetMapper.update(driverSet, queryWrapper);

        return true;
    }

    /**
     * 顾客查看配送员的基本信息
     */
    @Override
    public DriverInfoVo getDriverInfo(Long driverId) {
        DriverInfo driverInfo = getById(driverId);
        DriverInfoVo driverInfoVo = new DriverInfoVo();
        BeanUtils.copyProperties(driverInfo, driverInfoVo);

        //我们没有上传驾照信息，这里写死驾龄
        driverInfoVo.setDriverLicenseAge(5);

        return driverInfoVo;
    }
}